package com.beiding.hotcode.v2;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InvocationHandler;

public interface MyClass<TYPE> {

    Class<TYPE> getType();

    Object invokeCatch(String method, Object... params) throws Throwable;

    default Object invoke(String method, Object... params) {
        try {
            return invokeCatch(method, params);
        } catch (Throwable e) {
            if (e instanceof RuntimeException) {
                throw (RuntimeException) e;
            }
            RuntimeException runtimeException = new RuntimeException(e.getMessage(), e.getCause());
            runtimeException.setStackTrace(e.getStackTrace());
            throw runtimeException;
        }
    }

    //反射创建成对象
    default TYPE newObject(Object... params) {
        MyInstance<TYPE> typeMyInstance = newInstance(params);

        Enhancer enhancer = new Enhancer();

        //本地加载到的类???
        try {

            enhancer.setSuperclass(Thread.currentThread().getContextClassLoader().loadClass(typeMyInstance.getInstance().getClass().getName()));

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        enhancer.setCallback((InvocationHandler) (o, method, objects) -> typeMyInstance.invoke(method.getName(), objects));

        Object[] objects = new Object[typeMyInstance.parameterTypes.length];

        return (TYPE) enhancer.create(typeMyInstance.parameterTypes, objects);
    }


    void set(String field, Object value);

    Object get(String field);

    default <T> T get(String field, Class<T> type) {
        return (T) get(field);
    }

    MyInstance<TYPE> newInstance(Object... params);

    <T> MyMethod<T> method(String name, Class<T> type);

    default MyMethod method(String name) {
        return method(name, Object.class);
    }

}
